#pragma once

#include "Serializable.h"
#include "TeamAI.h"
#include "Vectors.h"
#include "TeamHistory.h"
#include "PeopleData.h"

#include "StlStringAndStreams.h"

class ServiceProvider;
class People;

struct TeamParams
{
	size_t GetMaxPeople(const bool i_isPlayer){return i_isPlayer ? MAX_TEAM_PLAYERS : MAX_TEAM_TRAINERS;}
	size_t GetMinPeople(const bool i_isPlayer){return i_isPlayer ? MIN_TEAM_PLAYERS : MIN_TEAM_TRAINERS;}
	size_t GetStartingPeople(const bool i_isPlayer){return i_isPlayer ? STARTING_TEAM_PLAYERS : STARTING_TEAM_TRAINERS;}

	size_t MAX_CHAR_TEAM_NAME;

	size_t STARTING_TEAM_PLAYERS;
	size_t MAX_TEAM_PLAYERS;
	size_t MIN_TEAM_PLAYERS; // must be GREATER OR EQUAL TO TITOLAR_PLAYERS

	size_t STARTING_TEAM_TRAINERS;
	size_t MAX_TEAM_TRAINERS;
	size_t MIN_TEAM_TRAINERS; // must be GREATER OR EQUAL TO 1 (maybe we can allow ZERO trainers...)
	
	size_t TITOLARS_PLAYERS;
};

enum ETeamFormation
{
	TEAM_FORMATION_202 = 0,
	TEAM_FORMATION_121,
	TEAM_FORMATION_040,
	NUM_TEAM_FORMATIONS
};

class Team : public Serializable
{
public:
	explicit Team(ServiceProvider* const i_sp, const STL::string& i_name = "", const int i_id = 0);

	static const TeamParams&	GetParams();

	void				EndTurnUpdate();

	void				SetName(STL::string i_name);
	const STL::string&	GetName() const;
	int					GetID() const;
	int					GetLeagueID() const {return m_leagueID;}
	void				SetLeagueID(const int i_leagueID) {m_leagueID = i_leagueID;}

	void				SetUserControlled(bool i_userControlled);
	bool				IsUserControlled() const;

	int					GetBudget() const;
	void				AddBudget(int i_budget);
	size_t				CalculateTotalSalary() const;
	int					GetBankruptWarnings() const {return m_bankruptWarnings;}

	int					GetTeamPower() const;

	bool				RemovePeople(People* i_player);
	bool				AddPeople(People* i_player, const bool i_createHistoryRecord = true);

	bool				BuyPlayer(People* i_player, const size_t price, const size_t years);
	bool				SellPlayer(People* i_player);
	void				SwapPlayers(int i_first, int i_second);
#ifndef DARIO
	bool                ContractExpires(People* i_player, const bool i_isPlayer);
	void				CheckRenewContract(STD::stringstream& o_message);
#endif

	size_t				GetNumPlayers() const;
	const PeopleVec&	GetPlayersList() const;

	size_t				GetNumTrainers() const;
	const PeopleVec&	GetTrainersList() const;
	void				SetTrainersList(const PeopleVec&);
	const People* const	GetTrainer(const size_t i_trainerIndex) const;
	People* const		GetTrainer(const size_t i_trainerIndex);

	People* const* const	GetTrainersRoleList() const;
	const People* const	GetTrainersRole(const size_t i_trainerRoleIndex) const;
	People* const		GetTrainersRole(const size_t i_trainerRoleIndex);
	void				SetTrainerRole(const size_t i_trainerIndex, const size_t i_trainerRoleIndex);
	int					GetTrainedRoles(const People* const i_trainer) const;

	int					GetRoleByIndex(int i_index) const;
	int					GetTitolarsByRole(const int i_role) const;

	TeamAI&				GetTeamAI();

	TeamHistory&		GetTeamHistory() {return m_teamHistory;}
	const TeamHistory&	GetTeamHistory() const {return m_teamHistory;}

	int GetTeamPoints(const int i_numYears = 0) const;
	void AddTeamPoints(const int i_points);
	void ClearTeamPoints();

	int GetFormation() const {return m_formation;}
	void SetFormation(const int i_formation) {m_formation = i_formation;}

	virtual	ZStream&	Serialize(ZStream& o_stream) const;
	virtual ZStream&	Deserialize(ZStream& i_stream);

	static const int NUM_TRAINERS_ROLES = NUM_SKILL_ROLES + 1;
	static const int TITOLAR_PER_ROLE_BY_FORMATION[NUM_TEAM_FORMATIONS][NUM_FORMATION_ROLES];
	static const int ROLE_ROLE_PERCENT_PLAYING[NUM_TEAM_FORMATIONS][NUM_FORMATION_ROLES][NUM_SKILL_ROLES];

private:
	//copy disabled
	Team(const Team&); 
	Team& operator=(const Team&);

	friend class TeamManager;
	friend class TeamAI;

	static TeamParams	s_params;

	ServiceProvider*	m_sp;
	STL::string			m_name;
	PeopleVec			m_players;
	PeopleVec			m_trainers;
	People*				m_trainerRoles[NUM_TRAINERS_ROLES];
	bool				m_userControlled;
	int					m_id;
	int					m_leagueID;
	TeamAI				m_ai;
	IntVec				m_teamPoints;
	TeamHistory			m_teamHistory;
	int					m_budget;
	int					m_bankruptWarnings;
	int					m_formation;
};

#include "Team.inl"